package org.opu.pc.sg;

import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Map;
import java.util.Properties;
import org.opu.pc.bl.BibliographyLinkService;
import org.opu.pc.domain.domains.Publisher;
import org.opu.pc.domain.domains.Publication;
import org.apache.commons.io.IOUtils;
import org.opu.pc.domain.PublisherManagement;
import org.opu.pc.ui.util.Logger;
import org.opu.pc.util.DateUtil;
import org.opu.pc.util.IOSafeUtils;
import static org.opu.pc.util.StringUtil.*;

/**
 *
 * @author Yuriy Dunko
 */
public class DepartmentStatementGenerator extends AbstractStatementGenerator {

    private Logger logger = Logger.create(DepartmentStatementGenerator.class);

    public static enum TableHeader {
        FOR_3_YEAR("publication.table.header.3year"),
        FOR_2_YEAR("publication.table.header.2year"),
        FOR_1_YEAR("publication.table.header.1year");

        public final String value;

        private TableHeader(String value) {
            this.value = value;
        }

    }

    public static final String TEMPLATE_PATH = "/org/opu/pc/sg/st1_template.docx";
    public static final String DOCUMENT = "/org/opu/pc/sg/st1_document.xml";
    public static final String AUTHORS = "/org/opu/pc/sg/st1_professor.xml";
    public static final String PUBLICATION = "/org/opu/pc/sg/st1_professor_publications.xml";
    public static final String PROPERTIES = "/org/opu/pc/sg/st1_properties.properties";

    private static final String DOCUMENT_TEMPLATE;
    private static final String AUTHORS_TEMPLATE;
    private static final String PUBLICATION_TEMPLATE;
    private static final Map<String, String> DOCUMENT_PROPERTIES;

    static {
        try {
            DOCUMENT_TEMPLATE = IOUtils.toString(IOSafeUtils.getResourceAsStream(DOCUMENT));
            AUTHORS_TEMPLATE = IOUtils.toString(IOSafeUtils.getResourceAsStream(AUTHORS));
            PUBLICATION_TEMPLATE = IOUtils.toString(IOSafeUtils.getResourceAsStream(PUBLICATION));

            Properties p = new Properties();
            p.load(IOSafeUtils.getResourceAsStream(PROPERTIES));
            DOCUMENT_PROPERTIES = Collections.unmodifiableMap(propertiesToMap(p));
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
    }

    private BibliographyLinkService linkService;
    private PublisherManagement publisherManagement;

    public DepartmentStatementGenerator(BibliographyLinkService linkService,
            PublisherManagement publisherManagement) {
        this.linkService = linkService;
        this.publisherManagement = publisherManagement;
    }

    @Override
    protected String getDocument() throws IOException {

        StringBuilder authors = new StringBuilder();
        Collection<Publisher> allAuthors = getAuthors();
        logger.debug("getDocument: get " + allAuthors.size() + " publishers.");
        for (Publisher author : allAuthors) {
            logger.debug("getDocument: publisher " + author.getLastName() +
                    " have " + author.getPublications().size() + " publications");

            StringBuilder publications = new StringBuilder();
            for (Publication p : author.getPublications()) {
                String link = linkService.createBibliographyLink(p);
                publications.append(assignVarValue(PUBLICATION_TEMPLATE,
                        toMap("link", link)));
                logger.debug("getDocument: \tlink: " + link);
            }

            authors.append(assignVarValue(AUTHORS_TEMPLATE, toMap(
                    "author.thurname", author.getSecondName(),
                    "author.name", author.getName(),
                    "author.lastname", author.getLastName(),
                    "publication.list", publications.toString())));

        }

        sgProperties.putAll(DOCUMENT_PROPERTIES);
        sgProperties.setProperty("publication.table.header",
                sgProperties.getProperty(getTableHeader().value));

        logger.debug("getDocument: properties: " + sgProperties);
        
        sgProperties.setProperty("professors", authors.toString());


        return assignVarValue(DOCUMENT_TEMPLATE, propertiesToMap(sgProperties));
    }

    private TableHeader getTableHeader(){
        Date start = (Date) variables.get(BEGIN_YEAR_VAR);
        Date end = (Date) variables.get(END_YEAR_VAR);
        int y1 = DateUtil.getYear(end);
        int y2 = DateUtil.getYear(start);
        int d = y1 - y2;

        logger.debug("getTableHeader: form " + y1 + " to " + y2 + " is " + d);

        if (d < 1) { // here must be 0, but just in case ...
            return TableHeader.FOR_1_YEAR;
        } else if (d < 2) { // here must be 1, but just in case ...
            return TableHeader.FOR_2_YEAR;
        } else {  // here must be 2, but just in case ...
            return TableHeader.FOR_3_YEAR;
        }
    }

    @Override
    protected String getTemplatePath() {
        return TEMPLATE_PATH;
    }

    private Collection<Publisher> getAuthors(){
        return publisherManagement.getPublishersWithPublications(
                (Date)variables.get(BEGIN_YEAR_VAR),
                (Date)variables.get(END_YEAR_VAR),
                false,
                null);
    }
}
